import React, { ReactNode } from 'react';
import { NetworkStatus } from '@apollo/client';
import { Box, Grid, GridItem, ListBase, Pill, Text } from '@nova-hf/ui';
import ContractsHeader from 'beta/components/contracts-header/ContractsHeader';
import { ErrorBanner } from 'beta/components/error/ErrorBanner';
import { CustomerMenuLayout } from 'beta/components/layouts/CustomerMenuLayout';
import Authentication from 'beta/store/authentication';
import { IContext } from 'beta/typings/context';
import { betaRoutingMaster, formatDate, formatPrice } from 'beta/utils/helpers';
import { useTranslation } from 'beta/utils/i18n';
import { inject, observer } from 'mobx-react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import {
  SubscriptionPeriodStatus,
  useContractInvoiceQuery,
  useCustomerNameQuery,
} from 'typings/graphql';

type ReikningurProps = {
  authentication?: Authentication;
};

const COLOR = 'blue';

const Reikningur = ({ authentication }: ReikningurProps) => {
  const router = useRouter();
  const { t } = useTranslation(['service', 'stillingar', 'errors']);
  const isStaff = authentication?.isStaff;
  const username = authentication?.username?.split(' ')[0];
  const customerId = (router?.query?.customerId as string) ?? '';
  const invoiceId = router?.query?.invoiceId ?? '';
  const {
    data: customerData,
    error: customerError,
    loading: customerLoading,
    refetch: customerRefetch,
  } = useCustomerNameQuery({
    variables: {
      input: {
        id: customerId.toString(),
      },
    },
  });
  const { data, error, loading, refetch, networkStatus } = useContractInvoiceQuery({
    variables: {
      input: {
        id: invoiceId.toString(),
      },
    },
  });

  const invoice = data?.contractsInvoice;
  const contractId = invoice?.contractId;
  const lines = invoice?.lines;
  const customer = customerData?.customer;
  const isPaid = invoice?.status === SubscriptionPeriodStatus.Paid;
  const startMonth = new Date(invoice?.periodStart);
  const endMonth = new Date(invoice?.periodEnd);
  const monthNames = [
    t('service:months.january'),
    t('service:months.february'),
    t('service:months.march'),
    t('service:months.april'),
    t('service:months.may'),
    t('service:months.june'),
    t('service:months.july'),
    t('service:months.august'),
    t('service:months.september'),
    t('service:months.october'),
    t('service:months.november'),
    t('service:months.december'),
  ];

  const customerClick = (customerId: string) => {
    betaRoutingMaster(
      `/beta/${customerId}/thjonustur`,
      router,
      customerData?.customer?.nationalId ?? '',
      '/beta/:customerId/thjonustur',
    );
  };

  if (!invoice || !data || loading || error || customerError || customerLoading) {
    return (
      <>
        <Box margin={30}>
          {loading && <ContractsHeader title={t('service:invoice.loading')} />}
          <ErrorBanner
            eyebrowTexts={[
              t('errors:reikningar.eyebrows.1'),
              t('errors:reikningar.eyebrows.2'),
              t('errors:reikningar.eyebrows.3'),
            ]}
            titles={[
              t('errors:reikningar.titles.1'),
              t('errors:reikningar.titles.2'),
              t('errors:reikningar.titles.3'),
            ]}
            descriptions={[
              t('errors:reikningar.descriptions.1'),
              t('errors:reikningar.descriptions.2'),
              t('errors:reikningar.descriptions.3'),
            ]}
            icon="zap"
            color="attention"
            showLoading={loading || networkStatus === NetworkStatus.refetch}
            refetchButton={{
              text: t('errors:buttons.refresh'),
              icon: 'refresh',
              onClick: () => (error ? refetch() : customerRefetch()),
            }}
            loadingComponent={
              <>
                <ListBase isLoading gap={3} />
                <ListBase isLoading gap={3} />
                <ListBase isLoading />
              </>
            }
          />
        </Box>
      </>
    );
  }

  return (
    <CustomerMenuLayout
      color={COLOR}
      isInverted={false}
      heroTitle={t('service:invoice.bill')}
      backButton={{
        renderAs: 'a',
        colorScheme: COLOR,
        text: t('customerMenu.back'),
        icon: 'longArrowLeft',
        wrapper: (link: ReactNode) => (
          <Link href={`/beta/${customerId}/askriftir/${contractId}`} passHref legacyBehavior>
            {link}
          </Link>
        ),
      }}
      title={t('service:invoice.bill')}
      subtitle={invoice?.lines[0]?.description ?? ''}
      icon="wallet"
      button={
        isStaff
          ? {
              renderAs: 'a',
              text: t('customerMenu.createNewTicket'),
              icon: 'add',
              colorScheme: 'white',
              dottedShadow: 'none',
              openInNewTab: true,
              href: 'https://novadesk.zendesk.com/agent/tickets/new/1',
            }
          : {
              text: t('customerMenu.needHelp'),
              icon: 'chat',
              colorScheme: 'white',
              dottedShadow: 'none',
              openInNewTab: true,
              href: 'https://support.nova.is/hc/is',
            }
      }
      details={[
        {
          label: customer?.nationalId ? t('service:invoice.nationalId') : '',
          value: customer?.nationalId || '',
        },
        {
          label: invoice?.periodStart && invoice?.periodEnd ? t('service:invoice.period') : '',
          value: `${formatDate(invoice?.periodStart, 'dd')}.${
            monthNames[startMonth.getMonth()]
          } - ${formatDate(invoice?.periodEnd, 'dd')}.${monthNames[endMonth.getMonth()]}`,
        },
        {
          label: invoice?.created ? t('service:invoice.date') : '',
          value: formatDate(invoice?.created, 'dd.MM.yyyy') || '',
        },
        {
          label: invoice?.payments[0]?.cardName ? t('customerMenu.payerMethod') : '',
          value: invoice?.payments[0]?.cardName ?? 'Heimabanki',
        },
        {
          label: invoice?.status ? t('service:invoice.status') : '',
          value: (
            <Pill
              color={isPaid ? 'green' : 'warning'}
              text={isPaid ? t('service:invoice.paid') : t('service:invoice.unpaid')}
            />
          ),
        },
        {
          label: invoice?.payments[0]?.message ? 'Skilaboð' : '',
          value: invoice?.payments[0]?.message ?? '',
        },
      ]}
      mainButton={{
        renderAs: 'a',
        text: t('service:invoice.payNow'),
        icon: !isPaid ? 'add' : undefined,
        colorScheme: isPaid ? 'grey200' : COLOR,
        isDisabled: isPaid,
        dottedShadow: 'none',
        openInNewTab: true,
        href: '',
      }}
      price={{
        monthlyPriceLabel: t('service:invoice.total'),
        monthlyPrice: invoice.totalAmount ?? 0,
      }}
      isStaff={isStaff}
      staffName={username}
      staffMenuLinks={[]}
      userLabel={t('customerMenu.user')}
      payerLabel={t('customerMenu.payer')}
      {...(isStaff &&
        customer && {
          user: {
            name: customer.name ?? '',
            nationalId: customer.nationalId ?? '',
            email: customer.email ?? '',
            ...(customer.id && {
              onClick: () => customerClick(customer.id ?? ''),
            }),
          },
        })}
    >
      <Box marginTop={-15}>
        <Box marginBottom={3}>
          <Grid gridTemplate={{ sm: 12 }} columnGap={3} rowGap={3}>
            <GridItem gridColumn={{ sm: 'span4' }}>
              <Text variant="eyebrowMedium" color="grey500">
                {t('service:invoice.service')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: 'span2' }}>
              <Text variant="eyebrowMedium" color="grey500">
                {t('service:invoice.quantity')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: 'span2' }}>
              <Text variant="eyebrowMedium" color="grey500">
                {t('service:invoice.discount')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: 'span4' }}>
              <Box display="flex" justifyContent="flex-end">
                <Text variant="eyebrowMedium" color="grey500">
                  {t('service:invoice.total')}
                </Text>
              </Box>
            </GridItem>
          </Grid>
        </Box>
        {lines?.map((line) => {
          return (
            <Box paddingY={5} borderY="solid" borderColor="grey200" key={line?.id}>
              <Grid gridTemplate={{ sm: 12 }} columnGap={3} rowGap={3}>
                <GridItem gridColumn={{ sm: 'span4' }}>
                  <Box>
                    <Text color={COLOR} variant="pMediumBold">
                      {line?.description}
                    </Text>
                  </Box>
                </GridItem>
                <GridItem gridColumn={{ sm: 'span2' }}>
                  <Text color={COLOR} variant="pMediumBold">
                    {line?.quantity}
                  </Text>
                </GridItem>
                <GridItem gridColumn={{ sm: 'span2' }}>
                  <Text color={COLOR} variant="pMediumBold">
                    {formatPrice(line?.discount ? line.discount : 0)}
                  </Text>
                </GridItem>
                <GridItem gridColumn={{ sm: 'span4' }}>
                  <Box display="flex" justifyContent="flex-end">
                    <Text color={COLOR} variant="pMediumBold">
                      {formatPrice(line?.amount ? line.amount : 0)}
                    </Text>
                  </Box>
                </GridItem>
              </Grid>
            </Box>
          );
        })}
        <Box marginTop={3}>
          <Grid gridTemplate={{ sm: 12 }} columnGap={3} rowGap={3}>
            <GridItem gridColumn={{ sm: 'span3' }}>
              <Text variant="pLargeBold">{t('service:invoice.total')}</Text>
            </GridItem>
            <GridItem gridColumn={{ sm: 'span6' }} />
            <GridItem gridColumn={{ sm: 'span3' }}>
              <Box display="flex" justifyContent="flex-end">
                <Text variant="pLargeBold">
                  {formatPrice(invoice?.totalAmount ? invoice?.totalAmount : 0)}
                </Text>
              </Box>
            </GridItem>
          </Grid>
        </Box>
        <Box marginTop={8} marginBottom={8}>
          <Text variant="h6">{t('service:invoice.taxDetails')}</Text>
        </Box>
        <Box width="9/12">
          <Box marginBottom={3}>
            <Grid gridTemplate={{ sm: 12 }} columnGap={3} rowGap={3}>
              <GridItem gridColumn={{ sm: 'span3' }}>
                <Text variant="eyebrowMedium" color="grey500">
                  {t('service:invoice.taxBase')}
                </Text>
              </GridItem>
              <GridItem gridColumn={{ sm: 'span3' }}>
                <Box display="flex" flexDirection="row" justifyContent="center">
                  <Text variant="eyebrowMedium" color="grey500">
                    {t('service:invoice.taxPercentage')}
                  </Text>
                </Box>
              </GridItem>
              <GridItem gridColumn={{ sm: 'span3' }}>
                <Text variant="eyebrowMedium" color="grey500">
                  {t('service:invoice.tax')}
                </Text>
              </GridItem>
              <GridItem gridColumn={{ sm: 'span3' }}>
                <Text variant="eyebrowMedium" color="grey500">
                  {t('service:invoice.totalWithTax')}
                </Text>
              </GridItem>
            </Grid>
          </Box>
          {lines?.map((line) => {
            return (
              <Box paddingY={5} borderY="solid" borderColor="grey200" key={line?.id}>
                <Grid gridTemplate={{ sm: 12 }} columnGap={3} rowGap={3}>
                  <GridItem gridColumn={{ sm: 'span3' }}>
                    {formatPrice(line?.tax && line?.amount ? line.amount - line.tax : 0)}
                  </GridItem>
                  <GridItem gridColumn={{ sm: 'span3' }}>
                    <Box display="flex" flexDirection="row" justifyContent="center">
                      {t('service:invoice.taxNumber')}
                    </Box>
                  </GridItem>
                  <GridItem gridColumn={{ sm: 'span3' }}>
                    {line?.tax ? formatPrice(line?.tax) : '0 kr.'}
                  </GridItem>
                  <GridItem gridColumn={{ sm: 'span3' }}>
                    {line?.amount ? formatPrice(line?.amount) : '0 kr.'}
                  </GridItem>
                </Grid>
              </Box>
            );
          })}
        </Box>
      </Box>
    </CustomerMenuLayout>
  );
};

Reikningur.getInitialProps = ({ pathname, query }: IContext) => {
  return {
    pathname,
    customerId: query.customerId,
    invoiceId: query.invoiceId,
    namespacesRequired: ['service', 'stillingar', 'errors'],
  };
};

export default inject('authentication')(observer(Reikningur));
